# ---------- 简介 ---------- #
# 流量生成器.py
# 生成一个数据流长度服从帕累托分布, 数据包到达时间服从泊松分布的数据包序列
# 赵宗义, xinshengzzy@foxmail.com, 2021.02.17
# -------------------- #
import numpy as np
import random
from network.通用工具 import 生成流标识符


class 帕累托流量生成器:
    def __init__(self, 帕累托参数, 泊松参数, 并发流数):
        random.seed(0)
        self.帕累托参数 = 帕累托参数
        self.泊松参数 = 泊松参数
        self.并发流数 = 并发流数
        np.random.seed(0)
        self.帕累托状态 = np.random.get_state()
        # ---------- #
        self.并发流 = dict()
        self.缓冲区 = []
        self.时钟 = 0
        self.初始化()

    def 获取时间戳(self):
        时间戳 = self.时钟/(10.0**9)
        self.时钟 += np.random.poisson(self.泊松参数)
        return 时间戳

    def 初始化(self):
        for 计数 in range(self.并发流数):
            self.增加流()
        random.shuffle(self.缓冲区)

    def 增加流(self):
        np.random.set_state(self.帕累托状态)
        流长度 = int(np.random.pareto(self.帕累托参数) + 1)
        self.帕累托状态 = np.random.get_state()
        # print(流长度, end="\t")
        标识符 = 生成流标识符()
        while 标识符 in self.并发流:
            标识符 = 生成流标识符()
        self.并发流[标识符] = 流长度
        for 甲 in range(流长度):
            self.缓冲区.append(标识符)
            索引 = random.randint(0, len(self.缓冲区) - 1)
            self.缓冲区[索引], self.缓冲区[-1] = self.缓冲区[-1], self.缓冲区[索引]

    def 打印并发流数(self):
        print("并发流数:%d" % len(self.并发流))

    def 生成数据包(self):
        标识符 = self.缓冲区[-1]
        时间戳 = self.获取时间戳()
        del self.缓冲区[-1]
        self.并发流[标识符] -= 1
        if 0 == self.并发流[标识符]:
            del self.并发流[标识符]
            self.增加流()
        return (标识符, 时间戳)
